package com.airbnb.lottie.parser;

import com.airbnb.lottie.parser.moshi.JsonReader;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

class JsonUtils {
    private JsonUtils() {
    }

    /**
     * [r,g,b]
     * @param reader JsonReader
     * @throws IOException
     * @return argb color
     */
    static int jsonToColor(JsonReader reader) throws IOException {
        reader.beginArray();
        int r = (int) (reader.nextDouble() * 255);
        int g = (int) (reader.nextDouble() * 255);
        int b = (int) (reader.nextDouble() * 255);
        while (reader.hasNext()) {
            reader.skipValue();
        }
        reader.endArray();
        return Color.argb(255, r, g, b);
    }

    static List<Point> jsonToPoints(JsonReader reader, float scale) throws IOException {
        List<Point> points = new ArrayList<>();

        reader.beginArray();
        while (reader.peek() == JsonReader.Token.BEGIN_ARRAY) {
            reader.beginArray();
            points.add(jsonToPoint(reader, scale));
            reader.endArray();
        }
        reader.endArray();
        return points;
    }

    static Point jsonToPoint(JsonReader reader, float scale) throws IOException {
        switch (reader.peek()) {
            case NUMBER:
                return jsonNumbersToPoint(reader, scale);
            case BEGIN_ARRAY:
                return jsonArrayToPoint(reader, scale);
            case BEGIN_OBJECT:
                return jsonObjectToPoint(reader, scale);
            default:
                throw new IllegalArgumentException("Unknown point starts with " + reader.peek());
        }
    }
    
	private static Point jsonNumbersToPoint(JsonReader reader, float scale) throws IOException {
        float x = (float) reader.nextDouble();
        float y = (float) reader.nextDouble();
        while (reader.hasNext()) {
            reader.skipValue();
        }
        return new Point(x * scale, y * scale);
    }
	
    private static Point jsonArrayToPoint(JsonReader reader, float scale) throws IOException {
        float x;
        float y;
        reader.beginArray();
        x = (float) reader.nextDouble();
        y = (float) reader.nextDouble();
        while (reader.peek() != JsonReader.Token.END_ARRAY) {
            reader.skipValue();
        }
        reader.endArray();
        return new Point(x * scale, y * scale);
    }



    private static final JsonReader.Options POINT_NAMES = JsonReader.Options.of("x", "y");

    private static Point jsonObjectToPoint(JsonReader reader, float scale) throws IOException {
        float x = 0f;
        float y = 0f;
        reader.beginObject();
        while (reader.hasNext()) {
            switch (reader.selectName(POINT_NAMES)) {
                case 0:
                    x = valueFromObject(reader);
                    break;
                case 1:
                    y = valueFromObject(reader);
                    break;
                default:
                    reader.skipName();
                    reader.skipValue();
            }
        }
        reader.endObject();
        return new Point(x * scale, y * scale);
    }

    static float valueFromObject(JsonReader reader) throws IOException {
        JsonReader.Token token = reader.peek();
        switch (token) {
            case NUMBER:
                return (float) reader.nextDouble();
            case BEGIN_ARRAY:
                reader.beginArray();
                float val = (float) reader.nextDouble();
                while (reader.hasNext()) {
                    reader.skipValue();
                }
                reader.endArray();
                return val;
            default:
                throw new IllegalArgumentException("Unknown value for token of type " + token);
        }
    }
}
